/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.hiruss.imageprocessor.ui;

import com.hiruss.imageprocessor.util.ImageHandler;
import com.hiruss.imageprocessor.util.Representation;
import com.hiruss.imageprocessor.util.Segmentation;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;

/**
 *
 * @author Hiru
 */
public class RepresentationPanel extends javax.swing.JDialog {

    private UI parent;
    private static RepresentationPanel instance;
    private static JFrame jFrameChain;

    /**
     * Creates new form CropPanel
     */
    private RepresentationPanel(UI parent, boolean modal) {
        super(parent, modal);
        this.parent = parent;
        initComponents();
        setLocationRelativeTo(parent);
    }

    public static RepresentationPanel getInstance(UI parent) {
        if (RepresentationPanel.instance == null) {
            RepresentationPanel.instance = new RepresentationPanel(parent, true);
        }
        instance.revertButton.setEnabled(false);
        return RepresentationPanel.instance;
    }

    private static JPanel getCodes(String codes) {
        JPanel showCodesPanel = new JPanel();
        showCodesPanel.setLayout(new GridBagLayout());

        showCodesPanel.add(new JLabel("Chain code"), new GridBagConstraints(0, 0, 1, 1, 0.1, 0.1,
                GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(3, 12, 3, 12), 0, 0));

        JTextArea jTextArea1 = new JTextArea();
        jTextArea1.setLineWrap(true);
        jTextArea1.setText(codes);
        showCodesPanel.add(jTextArea1, new GridBagConstraints(0, 1, 1, 1, 0.1, 0.9,
                GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(3, 12, 3, 12), 0, 0));

        showCodesPanel.add(new JLabel("Normalize starting point"), new GridBagConstraints(0, 2, 1, 1, 0.1, 0.1,
                GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(3, 12, 3, 12), 0, 0));

        JTextArea jTextArea2 = new JTextArea();
        jTextArea2.setLineWrap(true);
        jTextArea2.setText(Representation.normalizeStartingPoint(codes));
        showCodesPanel.add(jTextArea2, new GridBagConstraints(0, 3, 1, 1, 0.1, 0.9,
                GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(3, 12, 3, 12), 0, 0));

        showCodesPanel.add(new JLabel("Normalize rotation"), new GridBagConstraints(0, 4, 1, 1, 0.1, 0.1,
                GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(3, 12, 3, 12), 0, 0));

        JTextArea jTextArea3 = new JTextArea();
        jTextArea3.setLineWrap(true);
        jTextArea3.setText(Representation.normalizeRotation(codes));
        showCodesPanel.add(jTextArea3, new GridBagConstraints(0, 5, 1, 1, 0.1, 0.9,
                GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(3, 12, 3, 12), 0, 0));

        double perimeter = Representation.calculatePerimeter(codes);
        double area = Representation.calculateArea(codes);
        double compactness = Representation.calculateCompactness(perimeter, area);

        StringBuilder sb = new StringBuilder();
        sb.append("Perimeter = ").append(String.valueOf(perimeter)).append("\n");
        sb.append("Area=").append(String.valueOf(area)).append("\n");
        sb.append("Compactness=").append(String.valueOf(compactness)).append("\n");

        showCodesPanel.add(new JLabel("Calculations:"), new GridBagConstraints(0, 6, 1, 1, 0.1, 0.1,
                GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(3, 12, 3, 12), 0, 0));

        JTextArea jTextArea4 = new JTextArea();
        jTextArea4.setLineWrap(true);
        jTextArea4.setText(sb.toString());
        showCodesPanel.add(jTextArea4, new GridBagConstraints(0, 7, 1, 1, 0.1, 0.9,
                GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(3, 12, 3, 12), 0, 0));
        return showCodesPanel;
    }

    private static void showCodes(String codes) {
        if (jFrameChain != null) {
            jFrameChain.setVisible(false);
        }
        jFrameChain = new JFrame();
        GridLayout grid = new GridLayout(1, 1);
        jFrameChain.setLayout(grid);

        jFrameChain.add(getCodes(codes));

        jFrameChain.setBounds(50, 50, 700, 600);
        jFrameChain.setTitle("8-Directional chain code");
        jFrameChain.setVisible(true);
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        resamplingMethodButtonGroup = new javax.swing.ButtonGroup();
        jPanel1 = new javax.swing.JPanel();
        applyButton = new javax.swing.JButton();
        revertButton = new javax.swing.JButton();
        closeButton = new javax.swing.JButton();
        jPanel2 = new javax.swing.JPanel();
        chainCodeRadioButton = new javax.swing.JRadioButton();
        runCodeRadioButton = new javax.swing.JRadioButton();
        solutionLabel = new javax.swing.JLabel();
        chainCodesPanel = new javax.swing.JPanel();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("Representation");
        setBounds(new java.awt.Rectangle(0, 0, 400, 120));
        setMinimumSize(new java.awt.Dimension(620, 180));
        setModal(true);
        getContentPane().setLayout(new java.awt.GridBagLayout());

        jPanel1.setLayout(new java.awt.GridLayout(1, 3, 6, 0));

        applyButton.setText("Apply");
        applyButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                applyButtonActionPerformed(evt);
            }
        });
        jPanel1.add(applyButton);

        revertButton.setText("Revert");
        revertButton.setEnabled(false);
        revertButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                revertButtonActionPerformed(evt);
            }
        });
        jPanel1.add(revertButton);

        closeButton.setText("Close");
        closeButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                closeButtonActionPerformed(evt);
            }
        });
        jPanel1.add(closeButton);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 0.2;
        gridBagConstraints.insets = new java.awt.Insets(6, 12, 12, 12);
        getContentPane().add(jPanel1, gridBagConstraints);

        jPanel2.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));
        jPanel2.setLayout(new java.awt.GridBagLayout());

        resamplingMethodButtonGroup.add(chainCodeRadioButton);
        chainCodeRadioButton.setText("Chain Code");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 0.1;
        gridBagConstraints.insets = new java.awt.Insets(3, 6, 3, 3);
        jPanel2.add(chainCodeRadioButton, gridBagConstraints);

        resamplingMethodButtonGroup.add(runCodeRadioButton);
        runCodeRadioButton.setText("Run Code");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 0.1;
        gridBagConstraints.insets = new java.awt.Insets(3, 6, 3, 3);
        jPanel2.add(runCodeRadioButton, gridBagConstraints);

        solutionLabel.setText("Solution:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 0.9;
        gridBagConstraints.insets = new java.awt.Insets(3, 12, 6, 3);
        jPanel2.add(solutionLabel, gridBagConstraints);

        chainCodesPanel.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 0.2;
        gridBagConstraints.weighty = 0.2;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        jPanel2.add(chainCodesPanel, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 0.2;
        gridBagConstraints.weighty = 0.2;
        gridBagConstraints.insets = new java.awt.Insets(12, 12, 6, 12);
        getContentPane().add(jPanel2, gridBagConstraints);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void applyButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_applyButtonActionPerformed

        setCursor(new java.awt.Cursor(java.awt.Cursor.WAIT_CURSOR));
        applyButton.setEnabled(false);
        try {
            BufferedImage originalImage = parent.getEditingImage();
            BufferedImage destImage = ImageHandler.duplicateImage(originalImage);

            if (chainCodeRadioButton.isSelected()) {
                Segmentation.THRESHOLD = 128;
                destImage = Representation.chainCodes(originalImage);
                JPanel codes = getCodes(Representation.chainCode);
                chainCodesPanel.removeAll();
                chainCodesPanel.setLayout(new GridBagLayout());
                chainCodesPanel.add(new JLabel("8 Direction Chain Codes", JLabel.CENTER), new GridBagConstraints(0, 0, 1, 1, 0.1, 0.0,
                        GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(3, 12, 3, 12), 0, 24));
                chainCodesPanel.add(codes, new GridBagConstraints(0, 1, 1, 1, 0.1, 0.1,
                        GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(3, 12, 3, 12), 0, 0));

                this.setSize(this.getWidth(), 720);
                chainCodesPanel.repaint();
                repaint();

            } else if (runCodeRadioButton.isSelected()) {
                long area = Representation.applyRunCodes(destImage);
                solutionLabel.setText("Area: " + String.valueOf(area));
            }
            parent.setEditingImage(destImage);
            revertButton.setEnabled(true);
        } catch (Exception e) {
            JOptionPane.showMessageDialog(this,
                    e.getLocalizedMessage(),
                    "Invalid Inputs!",
                    JOptionPane.WARNING_MESSAGE);
        }
        applyButton.setEnabled(true);
        setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
    }//GEN-LAST:event_applyButtonActionPerformed

    private void revertButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_revertButtonActionPerformed

        parent.revert();
        revertButton.setEnabled(false);
    }//GEN-LAST:event_revertButtonActionPerformed

    private void closeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_closeButtonActionPerformed

        dispose();
    }//GEN-LAST:event_closeButtonActionPerformed
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton applyButton;
    private javax.swing.JRadioButton chainCodeRadioButton;
    private javax.swing.JPanel chainCodesPanel;
    private javax.swing.JButton closeButton;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.ButtonGroup resamplingMethodButtonGroup;
    private javax.swing.JButton revertButton;
    private javax.swing.JRadioButton runCodeRadioButton;
    private javax.swing.JLabel solutionLabel;
    // End of variables declaration//GEN-END:variables
}
